#------------------------------------------------------------------------------
#FreeCamera.py
#Created on 22.06.2009
#Author: Akuryou
#Contact: akuryou@l2si.de
#Version: 1.00
#------------------------------------------------------------------------------

from direct.showbase import DirectObject
from pandac.PandaModules import *

class FreeCamera(object, DirectObject.DirectObject):
    """This will give the player control over the camera via wasd and mouse"""
    def __init__(self, baseSpeed = 20, maxSpeed = 70, turnSpeed = 5):
        self.baseSpeed = baseSpeed
        self.maxSpeed = maxSpeed        
        self.speed = baseSpeed
        self.turnSpeed = turnSpeed
        self.FORWARD = Vec3(0,2,0)
        self.BACK = Vec3(0,-1,0)
        self.LEFT = Vec3(-1,0,0)
        self.RIGHT = Vec3(1,0,0)
        self.STOP = Vec3(0)
        
        self.walk = self.STOP
        self.strafe = self.STOP
        
        props = WindowProperties()
        props.setCursorHidden(1)
        base.win.requestProperties(props)
        base.disableMouse()
        self.addEvents()
        self.moveTaskP = taskMgr.add(self.moveTask, 'move-task')
        self.mouseLookTaskP = taskMgr.add(self.mouseLookTask, 'mouseLook-task')
        
    def addEvents(self):
        """Adds all necessary events"""
        self.accept( "w" , self.__setattr__,["walk",self.FORWARD])
        self.accept( "shift-w" , self.__setattr__,["walk",self.FORWARD])
        self.accept( "s" , self.__setattr__,["walk",self.BACK] )
        self.accept( "shift-s" , self.__setattr__,["walk",self.BACK] )
        self.accept( "s-up" , self.__setattr__,["walk",self.STOP] )
        self.accept( "w-up" , self.__setattr__,["walk",self.STOP] )
        self.accept( "a" , self.__setattr__,["strafe",self.LEFT])
        self.accept( "shift-a" , self.__setattr__,["strafe",self.LEFT])
        self.accept( "d" , self.__setattr__,["strafe",self.RIGHT] )
        self.accept( "shift-d" , self.__setattr__,["strafe",self.RIGHT] )
        self.accept( "a-up" , self.__setattr__,["strafe",self.STOP] )
        self.accept( "d-up" , self.__setattr__,["strafe",self.STOP] )
        self.accept( "shift" , self.__setattr__,["speed",self.maxSpeed] )
        self.accept( "shift-up" , self.__setattr__,["speed",self.baseSpeed] )
    
    def disableEvents(self):
        """Use this if you want to control the camera differently, use addEvents() to revert"""
        self.ignoreAll()
        
    def moveTask(self,task): 
        """ this task makes the player move """
        base.camera.setPos(base.camera,self.walk*globalClock.getDt()*self.speed)
        base.camera.setPos(base.camera,self.strafe*globalClock.getDt()*self.speed)
        return task.cont
    
    def mouseLookTask(self,task):
        """this task updates the looking direction"""
        md = base.win.getPointer(0)
        x = md.getX()
        y = md.getY()
        if base.win.movePointer(0, base.win.getXSize()/2, base.win.getYSize()/2):
            base.camera.setH(base.camera.getH() - (x - base.win.getXSize()/2)*globalClock.getDt()*self.turnSpeed)
            base.camera.setP(base.camera.getP() - (y - base.win.getYSize()/2)*globalClock.getDt()*self.turnSpeed)
            # here we set a limit to the camera angle
            if base.camera.getP() < -89:
                base.camera.setP(-89)
            if base.camera.getP() > 85:
                base.camera.setP(85)
        return task.cont            